package com.example.springbootdockertest.controller.order;

import cn.hutool.core.date.TimeInterval;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.example.springbootdockertest.entity.DO.OrderInfoDo;
import com.example.springbootdockertest.mapper.OrderInfoMapper;
import com.example.springbootdockertest.service.OrderInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author crush
 * @since 2022-04-03
 */
@Slf4j
@RestController
@RequestMapping("/orderInfoDo")
public class OrderInfoController {

    @Autowired
    private OrderInfoService orderInfoService;
    @Autowired
    private OrderInfoMapper mapper;

    @GetMapping("get")
    public OrderInfoDo getOrder() {
        return orderInfoService.getOrder();
    }

    @GetMapping("list")
    public List<OrderInfoDo> list() {
        return orderInfoService.getOrderList();
    }

    @GetMapping("threadOrder")
    public String threadOrder() {
        int size = 1000000;
        List<OrderInfoDo> orderInfoDos = new ArrayList<>(size);
        for (int i = 0; i < size; i++) {
            OrderInfoDo orderInfoDo = new OrderInfoDo();
            orderInfoDo.setTitle("" + i);
            orderInfoDo.setOrderNo("" + i);
            orderInfoDo.setUserId((long) i);
            orderInfoDo.setProductId(0L);
            orderInfoDo.setTotalFee(0);
            orderInfoDo.setCodeUrl("" + i);
            orderInfoDo.setOrderStatus("" + i);
            orderInfoDo.setCreateTime(LocalDateTime.now());
            orderInfoDo.setUpdateTime(LocalDateTime.now());


            orderInfoDos.add(orderInfoDo);
        }
        try {
            orderInfoService.threadOrderTrue(orderInfoDos);
            // mapper.saveBatch(orderInfoDos);
            System.out.println("添加成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 这是每批处理的大小
    private final static int BATCH_SIZE = 1000;
    private int size;
    // 存储每批数据的临时容器
    private List<OrderInfoDo> mallOrders = new ArrayList<>();

    @GetMapping(path = "/export")
    public void export(
            // @RequestParam(name = "paymentDateTimeStart") String paymentDateTimeStart,
            //            @RequestParam(name = "paymentDateTimeEnd") String paymentDateTimeEnd,
            HttpServletResponse response) throws Exception {
        TimeInterval timeInterval = new TimeInterval();
        timeInterval.start();
        String fileName = URLEncoder.encode(String.format("%s-(%s).xlsx", "订单支付数据", UUID.randomUUID().toString()),
                StandardCharsets.UTF_8.toString());
        response.setContentType("application/force-download");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        ExcelWriter writer = new ExcelWriterBuilder()
                .autoCloseStream(true)
                .excelType(ExcelTypeEnum.XLSX)
                .file(response.getOutputStream())
                .head(OrderInfoDo.class)
                .build();
        // xlsx文件上上限是104W行左右,这里如果超过104W需要分Sheet
        WriteSheet writeSheet = new WriteSheet();
        writeSheet.setSheetName("target");
        WriteSheet writeSheet1 = new WriteSheet();
        writeSheet1.setSheetName("target1");
        long lastBatchMaxId = 1100435L;
        // long lastBatchMaxId = 1L;
        int limit = 5000;
        int count = 0;
        TimeInterval timeInterval1 = new TimeInterval();
        String sql = "select * from t_order_info WHERE (id > 333935) LIMIT 5000";
        mapper.dynamicSelectLargeData1(sql, resultContext -> {
            OrderInfoDo tblMallOrder = resultContext.getResultObject();
            System.out.println(tblMallOrder);
            // 你可以看自己的项目需要分批进行处理或者单个处理，这里以分批处理为例
            mallOrders.add(tblMallOrder);
            size++;
            if (size == BATCH_SIZE) {
                handle(count, mallOrders, lastBatchMaxId, writer, writeSheet, writeSheet1, timeInterval1);
            }
        });


        // for (; ; ) {
        //     // List<OrderDTO> list = orderService.queryByScrollingPagination(paymentDateTimeStart, paymentDateTimeEnd, lastBatchMaxId, limit);
        //     QueryWrapper<OrderInfoDo> queryWrapper = new QueryWrapper<>();
        //     queryWrapper.gt("id", lastBatchMaxId);
        //     queryWrapper.last("limit " + limit);
        //     timeInterval1.start();
        //     List<OrderInfoDo> list = orderInfoService.list(queryWrapper);
        //     log.info("查询耗时{}", timeInterval1.intervalMs());
        //     if (CollectionUtils.isEmpty(list)) {
        //         log.info("完成数据耗时:{} ms,数量:{}", timeInterval.intervalMs(), count);
        //         writer.finish();
        //         break;
        //     } else {
        //         count = list.size() + count;
        //         lastBatchMaxId = list.stream().map(OrderInfoDo::getId).max(Long::compareTo).orElse(Long.MAX_VALUE);
        //         log.info("已下载数量{};lastBatchMaxId==>{}", count, lastBatchMaxId);
        //         if (count <= 1030000) {
        //             timeInterval1.start();
        //             writer.write(list, writeSheet);
        //             log.info("写出{}耗时{}", list.size(), timeInterval1.intervalMs());
        //         } else {
        //             writer.write(list, writeSheet1);
        //         }
        //     }
        // }
        log.info("导出数据耗时:{} ms,数量:{}", timeInterval.intervalMs(), count);
    }

    /**
     * 数据处理
     */
    private void handle(int count, List<OrderInfoDo> list, long lastBatchMaxId, ExcelWriter writer, WriteSheet writeSheet, WriteSheet writeSheet1, TimeInterval timeInterval1) {
        try {
            // 在这里可以对你获取到的批量结果数据进行需要的业务处理
            count = list.size() + count;
            lastBatchMaxId = list.stream().map(OrderInfoDo::getId).max(Long::compareTo).orElse(Long.MAX_VALUE);
            log.info("已下载数量{};lastBatchMaxId==>{}", count, lastBatchMaxId);
            if (count <= 1030000) {
                timeInterval1.start();
                writer.write(list, writeSheet);
                log.info("写出{}耗时{}", list.size(), timeInterval1.intervalMs());
            } else {
                writer.write(list, writeSheet1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 处理完每批数据后后将临时清空
            size = 0;
            this.mallOrders.clear();
        }
    }
}
